package com.lsp.microarticle.article.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lsp.microarticle.article.dao.ArticleLikeDao;
import com.lsp.microarticle.article.service.ArticleLikeService;
import com.lsp.microcommon.entity.ArticleLike;
import com.lsp.microcommon.utils.DateUtils;
import com.lsp.microcommon.utils.RedisUtils;
import com.lsp.microcommon.utils.UserUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

@Service
public class ArticleLikeServiceImpl implements ArticleLikeService {

    @Resource
    private ArticleLikeDao articleLikeDao;

    /**
     * 点赞和取消点赞调用同一个方法
     * 如果没有点赞进行点赞操作，
     * 否则取消点赞
     *
     * @param articleId
     */
    @Override
    public void like(Integer articleId) {
        //点赞数据存储到redis中
        String key = String.format("like:%s", articleId);

        String uid = UserUtils.getUser().toString();
//        取点赞数据 0没点赞  1点赞
        Integer likeFlag = (Integer) RedisUtils.hashGet(key, uid);
//        存储当天某个文章的点赞量
        String yearAndMouthAndDay = DateUtils.getYearAndMouthAndDay();
        String likeNumkey = String.format("like:%s", yearAndMouthAndDay);
        /**
         * 针对高并发，如何优化redis操作
         *      高并发情况下，就可能出现，连续点赞成功三次，而不是一次成功一次失败
         *      针对这情况：  1.将redis操作使用lua脚本(实现原子性操作)
         *                  2.分布式锁
         */
        if (likeFlag == null) {
//              如果没点赞，点赞
            RedisUtils.hashPut(key, uid, 1);
//            文章的点赞数+1
            RedisUtils.hashIncr(likeNumkey, articleId.toString(), 1);
//            点赞文章后将文章id和score存入zset
            RedisUtils.zsetAdd("article:rank",articleId.toString(),10);
//            暂时直接向数据库中添加点赞记录，后续会使用消息队列mq
            ArticleLike articleLike = new ArticleLike();
            articleLike.setUid(Integer.valueOf(uid));
            articleLike.setArticleId(articleId);
            articleLikeDao.insert(articleLike);
        } else {
//            从hash中删除数据
            RedisUtils.hashDeleteKeys(key, uid);
//            取消点赞，对文章的点赞数-1
            RedisUtils.hashIncr(likeNumkey, articleId.toString(), -1);
//            取消点赞文章后，修改score
            RedisUtils.zsetAdd("article:rank",articleId.toString(),-10);
//            从数据库中删除数据
            articleLikeDao.delete(new LambdaQueryWrapper<ArticleLike>()
                    .eq(ArticleLike::getUid, uid)
                    .eq(ArticleLike::getArticleId, articleId));
        }
    }

    @Override
    public List<ArticleLike> articleLikeList(Integer uid) {
        return articleLikeDao.selectList(new QueryWrapper<ArticleLike>().eq("uid",uid));
    }

    @Override
    public List<ArticleLike> likeList() {
        return articleLikeDao.selectList(null);
    }
}
